#! -*- coding:utf-8 -*-

import math
import numpy as np
from numpy import *
import matplotlib.pyplot as plt
import sys, os, time, uuid, re, codecs
import urllib2
import chardet
from bs4 import BeautifulSoup
from pymongo import MongoClient
import cPickle
import stock_data

#给K先矩阵设置买卖标签
def buildLabel(prices,data):
    labels = []
    lens = shape(data)[0]-1
    for i in range(0, lens):
        label = 0
        if isBuy(prices,data, i):
            label = 1
        elif isSale(prices,data, i):
            label = 2
        labels.append(label)
    return labels

# #验证收益率
# def validate(begin=30,lens=100):
#     print "开始验证收益率"
#     money = 100000
#     doubles=1
#     end = begin + lens
#     mats = []
#     trades = []
#
#     (prices, data) = getStrateryData('RU0')  # getPrices('RU0')   # data = getPrices('RU60t')
#     mat = np.matrix(data)
#     print "724 date:",prices[734][0]
#     print "RU length:",len(prices)
#     labels = buildLabel(prices,mat)
#     count = doubles * (money / data[3][1]) #math.ceil(money / data[3][1])
#     shouxu = count * 2
#     mats.append([prices, data, labels, count, shouxu])
#
#     (prices, data) = getStrateryData('AG0')  # getPrices('RU0')   # data = getPrices('RU60t')
#     mat = np.matrix(data)
#     labels = buildLabel(prices, mat)
#     count = doubles * (money / data[3][1])
#     shouxu = count * 2
#     mats.append([prices, data, labels, count, shouxu])
#
#     (prices, data) = getStrateryData('CU0')  # getPrices('RU0')   # data = getPrices('RU60t')
#     mat = np.matrix(data)
#     labels = buildLabel(prices, mat)
#     count = doubles * (money / data[3][1])
#     shouxu = count * 2
#     mats.append([prices,data,labels,count,shouxu])
#
#     (prices, data) = getStrateryData('ZN0')  # getPrices('RU0')   # data = getPrices('RU60t')
#     mat = np.matrix(data)
#     labels = buildLabel(prices, mat)
#     count = doubles * (money / data[3][1])
#     shouxu = count * 2
#     mats.append([prices, data, labels, count, shouxu])
#
#     (prices, data) = getStrateryData('M0')  # getPrices('RU0')   # data = getPrices('RU60t')
#     mat = np.matrix(data)
#     labels = buildLabel(prices, mat)
#     count = doubles * (money / data[3][1])
#     shouxu = count * 2
#     mats.append([prices, data, labels, count, shouxu])
#
#     (prices, data) = getStrateryData('Y0')  # getPrices('RU0')   # data = getPrices('RU60t')
#     mat = np.matrix(data)
#     labels = buildLabel(prices, mat)
#     count = doubles * (money / data[3][1])
#     shouxu = count * 2
#     mats.append([prices, data, labels, count, shouxu])
#
#     for index in range(begin, end):
#         for i in range(len(mats)):
#             row = mats[i]
#             prices = row[0]
#             if (len(prices)-30<index):
#                 continue
#             data = row[1]
#             labels = row[2]
#             count = row[3]
#             shouxu = row[4]
#             count=(doubles * money) / (prices[index-1][4])
#             if labels[index] == 1:
#                 money = money + (count * (prices[index][4] - prices[index][1])) - shouxu
#                 print "money:", money
#             elif labels[index] == 2:
#                 money = money - (count * (prices[index][4] - prices[index][1])) - shouxu
#                 print "money:", money
#         trades.append(money)
#
#     print trades
#     perrecude = 0.01
#     dt = np.matrix(trades)
#     print "dt shape:", shape(dt)
#     lens = len(trades) - 1
#     for i in range(lens - 1):
#         print min(trades[i + 1:lens])  # np.min(dt[:,index:-1])
#         if min(trades[i + 1:lens]) < trades[i] * (1 - perrecude):
#             perrecude = (trades[i] - min(trades[i + 1:lens])) / (trades[i])
#     print "mintrade:", min(trades), ",perreduce:", perrecude
#     return trades


def validateSingle(kind):
    print "开始验证收益率"
    money = 100000
    doubles=1
    dict={}

    trades = []
    (prices, data) = stock_data.getTrainingData(kind)  # getPrices('RU0')   # data = getPrices('RU60t')
    end = min(3000,len(prices)-30)
    mat = np.matrix(data)
    print "724 date:",prices[734][0]
    print "length:",len(prices)
    labels = buildLabel(prices,mat)
    print "labels:",labels
    count = doubles * money / prices[3][1] #math.ceil(money / data[3][1])
    bakcount=count
    print "price:", data[3][1],"count:",count
    shouxu = 0

    for index in range(2, end):
        #count=(doubles * money) / (prices[index-1][4])
        if (money>200000):
            count=bakcount*2
        if (money > 300000):
            count = bakcount*3
        if (money > 400000):
            count = bakcount * 4
        if labels[index] == 1 :
            if not dict.has_key(kind):
                dict[kind]=[labels[index],prices[index][1]]
                print "index:",index,"buy prcice:",prices[index][1]
            #money =afterbuyit(prices,mat,index,money,shouxu) #money + (count * (prices[index][4] - prices[index][1])) - shouxu
        elif labels[index] == 2:
            if not dict.has_key(kind):
                dict[kind] = [labels[index], prices[index][1]]
                print "index:",index,"sale prcice:", prices[index][1]
            #money = aftersaleit(prices, mat, index, money, shouxu) #money = money - (count * (prices[index][4] - prices[index][1])) - shouxu
        else:
            if dict.has_key(kind):
                if dict[kind][0]==1:
                    money = money+count*(prices[index][4]-dict[kind][1])-shouxu
                    print "index:",index,"even price:",prices[index][4],"owning:",prices[index][4]-dict[kind][1]
                else:
                    money = money -count*( prices[index][4] - dict[kind][1]) - shouxu
                    print "index:",index,"even price:",prices[index][4],"owning:", 0-count*( prices[index][4] - dict[kind][1])
                dict.clear()
        trades.append(money)
    print trades
    perrecude = 0.01
    dt=np.matrix(trades)
    print "dt shape:",shape(dt)
    lens = len(trades)-1
    for i in range(lens-1):
        print min(trades[i+1:lens]) #np.min(dt[:,index:-1])
        if min(trades[i+1:lens])<trades[i]*(1-perrecude):
            perrecude=(trades[i]-min(trades[i+1:lens]))/(trades[i])
    print "mintrade:",min(trades),",perreduce:",perrecude
    return trades

#日内操作
def validateSingle_EveryDay(kind):
    print "开始验证收益率"
    money = 100000
    doubles=1
    dict={}

    trades = []
    (prices, data) = stock_data.getTrainingData(kind)  # getPrices('RU0')   # data = getPrices('RU60t')
    end = min(3000,len(prices)-30)
    mat = np.matrix(data)
    print "724 date:",prices[734][0]
    print "length:",len(prices)
    labels = buildLabel(prices,mat)
    print "labels:",labels
    count = doubles * money / prices[3][1] #math.ceil(money / data[3][1])
    bakcount=count
    print "price:", data[3][1],"count:",count
    shouxu = 0

    for index in range(2, end):
        #count=(doubles * money) / (prices[index-1][4])
        if (money>200000):
            count=bakcount*2
        if (money > 300000):
            count = bakcount*3
        if (money > 400000):
            count = bakcount * 4
        if labels[index] == 1 :
            money = money + count * (prices[index][4] -prices[index][1]) - shouxu
        elif labels[index] == 2:
            money = money - count * (prices[index][4] - prices[index][1]) - shouxu
        trades.append(money)
    print trades
    perrecude = 0.01
    dt=np.matrix(trades)
    print "dt shape:",shape(dt)
    lens = len(trades)-1
    for i in range(lens-1):
        print min(trades[i+1:lens]) #np.min(dt[:,index:-1])
        if min(trades[i+1:lens])<trades[i]*(1-perrecude):
            perrecude=(trades[i]-min(trades[i+1:lens]))/(trades[i])
    print "mintrade:",min(trades),",perreduce:",perrecude
    return trades

def afterbuyit(prices,mat,index,money,shouxu):
    saleindex=index+1
    money=money+ prices[saleindex][4]-prices[index][1] - shouxu
    return money
def aftersaleit(prices,mat,index,money,shouxu):
    saleindex=index+1
    money=money- (prices[saleindex][4]-prices[index][1]) - shouxu
    return money

def stratery_even_buy():
    print "平仓买单"

def stratery_even_sale():
    print "平仓卖单"

def stratery_buy():
    print "买单"

def stratery_sale():
    print "卖单"

#购买信号
def isBuy(prices,data,index):
    asc = False
    index=index-1
    if data[index,0]>data[index,1] and data[index,1]>data[index,2] and data[index,2]>data[index,3]:
        asc = True
    if (prices[index+1][1]> 1.04 * prices[index][3]):
        asc = False
    return asc

def isSale(prices,data,index):
    desc = False
    index=index-1
    if data[index, 0] < data[index, 1] and data[index, 1] < data[index, 2] and data[index, 2] < data[index, 3]:
        desc = True
    if (prices[index+1][1] < 0.96 * prices[index][3]):
        desc = False
    return desc

#平仓多单
def isEvenBuy(prices,data,index):
    delta=0.02
    if data[index,0]<data[index,1] and data[index-2,0]-data[index,1]>delta*data[index,0]:
        return True
    return False

def isEvenSale(prices,data,index):
    delta = 0.02
    if data[index, 0] > data[index, 1] and data[index , 0] - data[index - 2, 0] > delta * data[index, 0]:
        return True
    return False
#观望
def isNull(data,index):
    return True



def doit():
    # get60minutes()
    # showAll()

    #(prices,data) =getStrateryData('RU0') #getPrices('RU0')   # data = getPrices('RU60t')
    # data.reverse()
    # showFigure(data,len(data))
    #mat = np.matrix(data)
    #labels = buildLabel(prices,mat)
    kind = 'CF0'
    trades = validateSingle(kind) #validate(2000,900)
    #trades = validate(100,3000)
    plt.style.use('ggplot')
    plt.title(kind)
    plt.ylabel('Price Value')
    plt.xlabel('Time')
    plt.plot(trades[0:-1], 'r')
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    print "begin fenxi..."
    # begin script
    doit()


'''
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD, RMSprop
from keras.layers.recurrent import LSTM
from keras.utils import np_utils
from keras.datasets import mnist
def l2_normalizer(vec):
    denom = np.sum([el ** 2 for el in vec])
    return [(el / math.sqrt(denom)) for el in vec]


def getdata():
    # tf_vector = [tf(word, doc) for word in vocabulary]
    # doc_term_matrix_l2 = []
    # for vec in doc_term_matrix:
    #    doc_term_matrix_l2.append(l2_normalizer(vec))
    # print np.matrix(doc_term_matrix)
    a = array([20, 30, 40, 50])
    b = linspace(0, pi, 3)
    a = arange(15).reshape(3, 5)
    np.zeros((3, 4))
    # label = np_utils.to_categorical(label, numClass)
    return (X_train, y_train)


def getmodel():
    print "build model..."
    # build the model: a single LSTM
    print('Build model...')
    maxlen = 40
    dims = 4
    model = Sequential()
    model.add(LSTM(128, input_shape=(maxlen, dims)))
    model.add(Dense(4))
    # model.add(LSTM(64))
    # model.add(Dense(4))
    model.add(Activation('softmax'))
    optimizer = RMSprop(lr=0.01)
    model.compile(loss='categorical_crossentropy', optimizer=optimizer)

    for mode, result in zip(modes, results):
        ax1.plot(result[0].epoch, result[0].history['val_acc'], label=mode)
        ax2.plot(result[0].epoch, result[0].history['val_loss'], label=mode)
    # not used anyway
    # for a single-input model with 2 classes (binary):
    model = Sequential()
    model.add(Dense(1, input_dim=784, activation='sigmoid'))
    model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['accuracy'])

    return model


def showmodel(model):
    from keras.utils.visualize_util import plot
    plot(model, to_file='model.png')


def main():
    model = getmodel()
    batch_size = 128
    epochs = 30
    # (X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features)
    (X_train, y_train) = getdata()
    start_time = time.time()
    history = model.fit(X_train, y_train,
                        batch_size=batch_size,
                        nb_epoch=epochs,
                        validation_data=(X_test, y_test))
    average_time_per_epoch = (time.time() - start_time) / epochs

    # generate dummy data
    data = np.random.random((1000, 784))
    labels = np.random.randint(2, size=(1000, 1))

    # train the model, iterating on the data in batches
    # of 32 samples
    model.fit(data, labels, nb_epoch=10, batch_size=32)
    score = model.evaluate(data, labels, batch_size=32)
    print "score:", score
    # print model.get_weights()
    print model.predict(data[:1])

    print "end model..."
'''